iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
自我挑戰組

Vscode 實作:用 HTML/CSS/JS 打造醫藥健康小工具箱系列 第 27 篇

Day 27:【全站記憶】 LocalStorage 應用(下):用 JSON.parse() 讀取歷史紀錄與一鍵清空 LocalStorage 資料庫

  • 分享至 

  • xImage
  •  

本篇文章目錄

  1. 前言:資料的反序列化與狀態復原
  2. 兩大核心流程拆解:初始化載入與安全清空機制
  3. 實戰 JS 開發:JSON.parse() 恢復狀態與清空監聽
  4. 程式碼重點與體驗細節解析
  5. 結語

一、 前言:資料的反序列化與狀態復原

在上一篇文章中,我們學會了如何使用 JSON.stringify() 將陣列轉為字串並寫入 LocalStorage。但是,光是會把資料「存進去」還不夠;當使用者第二天重新打開網站時,我們必須能在網頁載入的第一時間,將這些字串「抓出來」並還原成可操作的 JavaScript 物件陣列。

此外,當使用者想要重新開始、或是資料累積過多時,我們也必須提供一個安全且具備防呆確認的「一鍵清空」機制。

今天作為 LocalStorage 系列的下集,我們將重點放在 JSON.parse() 反序列化讀取、預設空陣列容錯,以及 雙重確認(Confirm)的一鍵清空功能。

二、 兩大核心流程拆解:初始化載入與安全清空機制

在撰寫程式碼之前,我們先來拆解初始化與資料銷毀這兩個關鍵階段的設計思維:

1. 初始化讀取與反序列化(Deserialization):

當網頁準備就緒時,程式必須主動執行以下步驟:

  • 讀取原始字串:使用 localStorage.getItem("key") 從瀏覽器拉取資料。
  • 解析與降級(Fallback):若使用者是第一次存取網站(getItem 回傳 null),必須透過邏輯或運算子 || [] 自動降級為空陣列,防止 JSON.parse(null) 後續引發TypeError。
  • 觸發首次渲染:呼叫 renderTimers() 將恢復後的陣列轉化為 DOM 節點。

2. 雙重防範的一鍵清空流程(Clear Storage):

「清空」屬於破壞性操作(Destructive Action),為了避免使用者誤觸造成資料無法挽回的遺憾,必須建立兩道防線:

  • 防線一:空狀態攔截:當陣列長度為 0 時,直接阻止清空流程並給予提示。
  • 防線二:原生視窗二次確認(Confirm Window):透過 confirm() 跳出警示視窗,明確告知「此動作無法復原」,只有使用者按下確定後才執行資料抹除。

三、 實戰 JS 開發:JSON.parse() 恢復狀態與清空監聽

我們在 /tool4-timer.js 與 /tool3-schedule.js 中實現資料讀取、空狀態渲染與清空事件監聽:

/tool4-timer.js

// 1. 初始化:從 LocalStorage 載入歷史紀錄
let timerItems = JSON.parse(localStorage.getItem("med_timer_list")) || [];
renderTimers();

// 3. 一鍵清空事件
if (btnClearTimers) {
  btnClearTimers.addEventListener("click", () => {
    if (timerItems.length === 0) {
      alert("目前沒有任何追蹤中的開瓶項目!");
      return;
    }
    if (confirm("確定要清空所有開瓶倒數追蹤紀錄嗎?此動作無法復原!")) {
      timerItems = [];
      saveAndRender();
    }
  });
}

function renderTimers(){
  timerList.innerHTML = "";

  if (timerItems.length === 0) {
    timerList.innerHTML = `<p style="color: var(--text-muted); font-size: 0.9rem; text-align: center; padding: 20px 0;">目前尚無追蹤中的開瓶藥品</p>`;
    return;
  }
  // ...渲染節點邏輯
}

/tool3-schedule.js

// 4. 新增:一鍵清空事件
if (btnClearSchedule) {
  btnClearSchedule.addEventListener("click", () => {
    if (medList.length === 0) {
      alert("目前時間表中沒有任何項目!");
      return;
    }
    if (confirm("確定要清空用藥時間表中的所有藥品嗎?此動作無法復原!")) {
      medList = [];
      saveAndRender();
    }
  });
}

四、 程式碼重點與體驗細節解析

1. JSON.parse() 與短路運算子 || [] 的完美搭配

JSON.parse(localStorage.getItem("med_timer_list")) || [] 是非常經典的 JS 防禦性寫法。
當 key 值不存在時,getItem() 會回傳 null。在 JavaScript 中 JSON.parse(null) 結果雖然是 null,但 null屬於 Falsy 值,這時短路運算子 || 就會發揮作用,自動將變數初始化為空陣列 []。這確保了 timerItems 與 medList 永遠都是合法且可進行 .push() 或 .length 操作的陣列物件!

2. 衛語句(Guard Clause)雙重防呆驗證

在點擊清空按鈕時,我們第一時間進行長度檢查:
if (timerItems.length === 0) { alert(...); return; }
如果畫面上本來就沒有資料,就不應該跳出令人困惑的「確定要清空嗎」詢問視窗,而是直接提示無資料可清空並終斷執行(return),減少不必要的視覺干擾。

3. 原生 confirm() 破壞性操作警示

使用 confirm("此動作無法復原!") 建立第二道對話框防線。只有當使用者明確點擊「確定」回傳 true 時,才會將記憶體中的陣列歸零(timerItems = []),隨後呼叫 saveAndRender() 一併更新 LocalStorage 與畫面。

4. 空狀態(Empty State)之 UI 友善提示

當陣列被清空或剛好無任何項目時,renderTimers() 透過條件分支輸出帶有 --text-muted 的預設提示字串。這屬於重要卻常被忽略的 UI/UX 細節——避免留下一片空白的容器,讓使用者以為網頁發生錯誤或當機。

五、 結語

今天我們成功透過 JSON.parse() 實現了開頁時的歷史紀錄反序列化復原,並搭配安全確認機制完成了一鍵清空功能,正式讓 [Tool 3] 與 [Tool 4] 擁有了完整且穩健的 LocalStorage 資料生命週期管理。

在明天的 [Day 28] 中,我們將展開全站最終的收尾工作:[全站 RWD 響應式優化與跨裝置視覺校正],針對手機、平板與桌機進行排版微調,確保這套醫療輔助工具在各種裝置上都能呈現最完美的質感。鐵人賽最後倒數 3 天,我們明天見!


上一篇
Day 26:【全站記憶】 LocalStorage 應用(上):用 JSON.stringify() 實現 Tool 3 與 Tool 4 紀錄永久化儲存
下一篇
Day 28:【系統整合】Tab 切換選單:用 JS 實作單頁應用(SPA)風格的 4 個工具頁面切換
系列文
Vscode 實作:用 HTML/CSS/JS 打造醫藥健康小工具箱 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言